import { getErrorStack } from "../utils/get-error-stack";
import getLastEvent from "../utils/get-last-event";
import getSelectors from "../utils/get-selector";
import tracker from "../utils/tracker";

function catchJSError() {
  // JS语法错误
  window.addEventListener("error", function (event) {
    console.log("JS错误", event);
    if (event.target && (event.target.src || event.target.href)) {
      // js 或 css 资源加载错误
      const resourceErrorParams = {
        kind: "stability",
        type: "error",
        errorType: "resourceError",
        filename: event.target.src || event.target.href,
        tagName: event.target.tagName,
        selector: getSelectors(event.target),
      };
      console.log("resourceErrorParams", resourceErrorParams);
      tracker.send(resourceErrorParams);
    } else {
      // js 语法错误
      let lastEvent = getLastEvent();
      const JSErrorParams = {
        kind: "stability",
        type: "error",
        errorType: "jsError",
        message: event.message,
        filename: event.filename,
        position: `${event.lineno}:${event.colno}`,
        stack: getErrorStack(event.error.stack),
        selector: lastEvent ? getSelectors(lastEvent.path) : "",
      };
      console.log("JSErrorParams", JSErrorParams);
      tracker.send(JSErrorParams);
    }
  }, true);

  // Promise.reject 错误
  window.addEventListener("unhandledrejection", (event) => {
    console.log("Promise.reject 错误", event);
    let lastEvent = getLastEvent();
    let message;
    let reason = event.reason;
    let filename;
    let line = 0;
    let column = 0;
    let stack = "";
    if (typeof reason === "string") {
      message = reason;
    } else if (typeof reason === "object") {
      message = reason.message;
      if (reason.stack) {
        let matchResult = reason.stack.match(/at\s+(.+):(\d+):(\d+)/);
        filename = matchResult[1];
        line = matchResult[2];
        column = matchResult[3];
      }
      stack = getErrorStack(reason.stack);
    }
    const promiseErrorParams = {
      kind: "stability",
      type: "error",
      errorType: "promiseError",
      message,
      filename,
      position: `${line}:${column}`,
      stack,
      selector: lastEvent ? getSelectors(lastEvent.path) : "",
    };
    console.log("promiseErrorParams", promiseErrorParams);
    tracker.send(promiseErrorParams);
  });
}

export default catchJSError;
